<?php

class DataBaseController extends BaseController
{
	//数据库文件存放路径
	public $dataPath;
	
	//数据库备份信息
	public $dbinfo;
	
	//数据库备份信息文件
	public $infoFile;
	
	//初始化
	public function int(){
		$this->dataPath = Yii::getPathOfAlias(Yii::app()->params['bataBasePath']);
		$this->infoFile = $this->dataPath.DIRECTORY_SEPARATOR."dbinfo.php";
		if(!is_file($this->infoFile)) {
			$handle = fopen($this->infoFile, "wb");
			fwrite($handle, "<?php\n return array();\n?>");
			fclose($handle);
		}
		$this->dbinfo = include($this->infoFile);
	}
	
	/**
	 * 数据库备份管理
	 */
	public function actionAdmin()
	{
		$this->int();
		$this->render('admin');
	}

	/**
	 * 数据库备份
	 */
	public function actionBackup(){
		$this->int();
		//提取数据库SQL文件
		$sql = $this->sqldumptable();
		$filepath =  $this->dataPath.DIRECTORY_SEPARATOR.date('Ymd-His').'-'.rand(001,999);
		if(!Tool::makedir($filepath)){
			$this->throwException('创建目录失败,请检查磁盘空间或者权限!');
		}
		//生成SQL文件
		foreach($sql as $key=>$val){
			$sqlFile = $filepath.DIRECTORY_SEPARATOR."database_{$key}.sql";
			if(!is_file($sqlFile)) {
				$handle = fopen($sqlFile, "wb");
				fwrite($handle, $val);
				fclose($handle);
			}
		}
		//生成备份信息文件,转存XML
		$sqlinfo['time'] = time();
		$sqlinfo['describe'] = $_POST['describe'];
		//生成SQL信息文件
		$infoFile = $filepath.DIRECTORY_SEPARATOR."datainfo.php";
		if(!is_file($infoFile)) {
			$handle = fopen($infoFile, "wb");
			fwrite($handle,"<?php \n return array(\n".$this->arraytostr($sqlinfo)."\n);\n?>");
			fclose($handle);
		}
		//更新备份信息文件
		$backupinfo = array('pretime'=>time());
		$handle = fopen($this->infoFile, "wb");
		fwrite($handle,"<?php \n return array(\n".$this->arraytostr($backupinfo)."\n);\n?>");
		fclose($handle);
		
		//成功跳转
		$this->redirect(Yii::app()->request->urlReferrer);
	}
	
	/**
	 * 数据库还原
	 */
	public function actionRefresh($id){
		$this->int();
		$filepath = $this->dataPath.DIRECTORY_SEPARATOR.trim($id);
		$sqlfile = scandir($filepath);
		$sql = "";
		foreach($sqlfile as $val){
			$ext = strrchr($val, '.');
			if($ext == '.sql'){
				$sql .= file_get_contents($filepath.DIRECTORY_SEPARATOR.$val);
			}
		}
		if(!empty($sql)){
			Yii::app()->db->createCommand()->setText($sql)->execute();
			//成功跳转
			$this->redirect(Yii::app()->request->urlReferrer);
		}
	}
	
	/**
	 * 删除数据库备份文件
	 */
	public function actionDelete($id){
		$this->int();
		$filepath = $this->dataPath.DIRECTORY_SEPARATOR.trim($id);
		//删除目录和目录下的文件
		Tool::deleteDir($filepath);
		//成功跳转
		$this->render('../index/success',array('message'=>'恭喜，删除成功！'));
		exit;
	}
	
	
	/**
	 * 生成SQL文件
	 */
	public function sqldumptable(){
		//当前数据库名
		$dataBaseName = Yii::app()->db->createCommand()->setText('select database()')->queryRow();
		$dataBaseName = $dataBaseName['database()'];
		$tables = Yii::app()->db->createCommand()->setText('show tables')->queryAll();
		
		foreach($tables as $table){
			$sql = "";
			//创建数据表
			$tableName = $table["Tables_in_{$dataBaseName}"];
			$tablesql = Yii::app()->db->createCommand()->setText("SHOW CREATE TABLE {$tableName}")->queryRow();
            $sql .= "\r\n\r\n-- ----------------------------\r\n";
            $sql .= "-- 创建表结构 {$tableName}\r\n";
            $sql .= "-- ----------------------------";
      //    $tableCreateSql = str_replace(",",",\r\n",$tablesql['Create Table']);
            $tableCreateSql = $tablesql['Create Table'];
            $sql .= "\r\n DROP TABLE IF EXISTS {$tablesql['Table']};\r\n {$tableCreateSql};\r\n";

            //创建数据
            $data = Yii::app()->db->createCommand()->setText("SELECT * FROM {$tableName}")->queryAll();
            if(!empty($data)){

	            foreach($data as $tableDateRow){
	            	//组合INSERT的VALUE
	            	foreach ($tableDateRow as &$v) {
	            		$v = "'" . addslashes($v) . "'"; //别忘了转义.
	            	}
	            	$valuesArr[] = '(' . implode(',', $tableDateRow) . ')';
	            }
	            $sql .= "-- ----- 插入数据{$tableName}";
	            $temp = $this->chunkArrayByByte($valuesArr);
	            if (is_array($temp)) {
	            	foreach ($temp as $v) {
	            		$values = implode(',', $v) . ';';
	            		//空的数据表就不组合SQL语句了..因为没得组合
	            		if ($values != ';') {
	            			$sql .= "\r\n INSERT INTO {$tableName} VALUES {$values}";
	            		}
	            	}
	            }
	            unset($valuesArr);
            }
            $sqltablearr[] = $sql;
		}
		//文件分割
		$sqlfile = $this->chunkArrayByByte($sqltablearr,F::setting('sqlfile_size'));
		//sql 文加入备注说明
		foreach ($sqlfile as $key=>&$v) {
			$databaseinfo = "/*\r\n    Source Database       : {$dataBaseName}";
			$databaseinfo .= "\r\n    Backup Date           : ".date('Y-m-d H:i:s');
			$databaseinfo .= "\r\n    Part Date             : 第".($key+1)."个文件，共".count($sqlfile)."个文件\r\n*/";
			$v = $databaseinfo.implode('/*tabalsql Separation*/', $v); 
		}
		return $sqlfile;
	}
	
	/**
	 * 将数组按照字节数分割成小数组
	 *
	 * @param array $array  数组
	 * @param int $byte     字节数
	 * @return array
	 */
	private function chunkArrayByByte($array, $byte = 5120) {
		$i=0;
		$sum=0;
		foreach ($array as $v) {
			$sum += strlen($v);
			if ($sum < $byte) {
				$return[$i][] = $v;
			} elseif ($sum == $byte) {
				$return[$i][] = $v;
				$i++;
				$sum = 0;
			} else {
				$return[++$i][] = $v;
				$sum = 0;
			}
		}
		return $return;
	}
	
	/**
	 * 数据成功字符串
	 */
	public function arraytostr($arr){
		$str = "";
		foreach($arr as $key=>$val){
			$str .= "\t'".$key."'=>'".$val."',\n";
		}
		return $str;
	}
}